package com.fusheng.utils;

import android.os.Looper;
import android.util.Log;
import android.util.LogPrinter;
 
public class LogMonitorPrinter extends LogPrinter {
    private static final String TAG = "LogMonitorPrinter";
    private long beginTime;
    private int timeoutInterval = 1000;
    private MonitorThread monitorThread;
 
    /**
     * Create a new Printer that sends to the log with the given priority
     * and tag.
     *
     * @param priority The desired log priority:
     *                 {@link Log#VERBOSE Log.VERBOSE},
     *                 {@link Log#DEBUG Log.DEBUG},
     *                 {@link Log#INFO Log.INFO},
     *                 {@link Log#WARN Log.WARN}, or
     *                 {@link Log#ERROR Log.ERROR}.
     * @param tag      A string tag to associate with each printed log statement.
     */
    public LogMonitorPrinter(int priority, String tag) {
        super(priority, tag);
    }
 
 
    public void setTimeoutInterval(int interval) {
        this.timeoutInterval = interval;
    }
 
    @Override
    public void println(String x) {
        if (x.startsWith(">>>>> Dispatching to")) {
            beginTime = System.currentTimeMillis();
            monitorThread = new MonitorThread(timeoutInterval);
            monitorThread.start();
        }
 
        if (x.startsWith("<<<<< Finished to")) {
            long taskTime = System.currentTimeMillis() - beginTime;
            monitorThread.interrupt();
            if (taskTime > timeoutInterval) {
                Log.w(TAG, "taskTime: " + taskTime);
            }
        }
        super.println(x);
    }
 
    private static String getMainStackTrace() {
        StackTraceElement[] stackTraceElements = Looper.getMainLooper().getThread().getStackTrace();
        StringBuilder sb = new StringBuilder();
        for (StackTraceElement element : stackTraceElements) {
            sb.append(element.toString());
            sb.append("\n");
        }
        return sb.toString();
    }
 
    static class MonitorThread extends Thread {
        private long interval;
 
        public MonitorThread(int interval) {
            this.interval = interval;
        }
 
        @Override
        public void run() {
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e) {
                return;
            }
 
            Log.w("ERROR==", getMainStackTrace());
        }
    }
}